/*
 * Copyright (C) 2006 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.widget;

import android.graphics.Bitmap;
import android.graphics.Canvas;

import android.graphics.Matrix;

import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;

import android.util.Log;
import android.view.View;

/**
 * Displays an arbitrary image, such as an icon. The ImageView class can load
 * images from various sources (such as resources or content providers), takes
 * care of computing its measurement from the image so that it can be used in
 * any layout manager, and provides various display options such as scaling and
 * tinting.
 * 
 * @attr ref android.R.styleable#ImageView_adjustViewBounds
 * @attr ref android.R.styleable#ImageView_src
 * @attr ref android.R.styleable#ImageView_maxWidth
 * @attr ref android.R.styleable#ImageView_maxHeight
 * @attr ref android.R.styleable#ImageView_tint
 * @attr ref android.R.styleable#ImageView_scaleType
 */

public class ImageView extends View {
	// settable by the client
	// private Uri mUri;
	// private int mResource = 0;
	//private Matrix mMatrix;
	private int mScaleType;
	private boolean mHaveFrame = false;
	private boolean mAdjustViewBounds = false;
	private int mMaxWidth = Integer.MAX_VALUE;
	private int mMaxHeight = Integer.MAX_VALUE;

	// these are applied to the drawable
	// private ColorFilter mColorFilter;
	// private int mAlpha = 255;
	private int mViewAlphaScale = 256;

	private Drawable mDrawable = null;
	private int[] mState = null;
	private boolean mMergeState = false;
	private int mLevel = 0;
	private int mDrawableWidth;
	private int mDrawableHeight;

	// private Matrix mDrawMatrix = null;

	// Avoid allocations...
	//private RectF mTempSrc = new RectF();
	//private RectF mTempDst = new RectF();

	private boolean mCropToPadding = false;

	private boolean mBaselineAligned = false;

	/**
	 * Scale using the image matrix when drawing. The image matrix can be set
	 * using {@link ImageView#setImageMatrix(Matrix)}. From XML, use this
	 * syntax: <code>android:scaleType="matrix"</code>.
	 */
	public final static int SCALE_TYPE_MATRIX = (0);
	/**
	 * Scale the image using {@link Matrix.ScaleToFit#FILL}. From XML, use this
	 * syntax: <code>android:scaleType="fitXY"</code>.
	 */
	public final static int SCALE_TYPE_FIT_XY = (1);
	/**
	 * Scale the image using {@link Matrix.ScaleToFit#START}. From XML, use this
	 * syntax: <code>android:scaleType="fitStart"</code>.
	 */
	public final static int SCALE_TYPE_FIT_START = (2);
	/**
	 * Scale the image using {@link Matrix.ScaleToFit#CENTER}. From XML, use
	 * this syntax: <code>android:scaleType="fitCenter"</code>.
	 */
	public final static int SCALE_TYPE_FIT_CENTER = (3);
	/**
	 * Scale the image using {@link Matrix.ScaleToFit#END}. From XML, use this
	 * syntax: <code>android:scaleType="fitEnd"</code>.
	 */
	public final static int SCALE_TYPE_FIT_END = (4);
	/**
	 * Center the image in the view, but perform no scaling. From XML, use this
	 * syntax: <code>android:scaleType="center"</code>.
	 */
	public final static int SCALE_TYPE_CENTER = (5);
	/**
	 * Scale the image uniformly (maintain the image's aspect ratio) so that
	 * both dimensions (width and height) of the image will be equal to or
	 * larger than the corresponding dimension of the view (minus padding). The
	 * image is then centered in the view. From XML, use this syntax:
	 * <code>android:scaleType="centerCrop"</code>.
	 */
	public final static int SCALE_TYPE_CENTER_CROP = (6);
	/**
	 * Scale the image uniformly (maintain the image's aspect ratio) so that
	 * both dimensions (width and height) of the image will be equal to or less
	 * than the corresponding dimension of the view (minus padding). The image
	 * is then centered in the view. From XML, use this syntax:
	 * <code>android:scaleType="centerInside"</code>.
	 */
	public final static int SCALE_TYPE_CENTER_INSIDE = (7);

	private static final int[] sScaleTypeArray = {  SCALE_TYPE_MATRIX,
													SCALE_TYPE_FIT_XY, 
													SCALE_TYPE_FIT_START, 
													SCALE_TYPE_FIT_CENTER,
													SCALE_TYPE_FIT_END, 
													SCALE_TYPE_CENTER, 
													SCALE_TYPE_CENTER_CROP,
													SCALE_TYPE_CENTER_INSIDE };

	public ImageView() {
		super();
		initImageView();

		mBaselineAligned = false;
		setMaxWidth(Integer.MAX_VALUE);
		setMaxHeight(Integer.MAX_VALUE);
		mCropToPadding = false;
		/*
		 * TypedArray a = context.obtainStyledAttributes(attrs,
		 * com.android.internal.R.styleable.ImageView, defStyle, 0);
		 * 
		 * Drawable d =
		 * a.getDrawable(com.android.internal.R.styleable.ImageView_src); if (d
		 * != null) { setImageDrawable(d); }
		 * 
		 * mBaselineAligned = a.getBoolean(
		 * com.android.internal.R.styleable.ImageView_baselineAlignBottom,
		 * false);
		 * 
		 * setAdjustViewBounds(
		 * a.getBoolean(com.android.internal.R.styleable.ImageView_adjustViewBounds
		 * , false));
		 * 
		 * setMaxWidth(a.getDimensionPixelSize(
		 * com.android.internal.R.styleable.ImageView_maxWidth,
		 * Integer.MAX_VALUE));
		 * 
		 * setMaxHeight(a.getDimensionPixelSize(
		 * com.android.internal.R.styleable.ImageView_maxHeight,
		 * Integer.MAX_VALUE));
		 * 
		 * int index =
		 * a.getInt(com.android.internal.R.styleable.ImageView_scaleType, -1);
		 * if (index >= 0) { setScaleType(sScaleTypeArray[index]); }
		 * 
		 * int tint = a.getInt(com.android.internal.R.styleable.ImageView_tint,
		 * 0); if (tint != 0) { setColorFilter(tint, PorterDuff.Mode.SRC_ATOP);
		 * }
		 * 
		 * mCropToPadding = a.getBoolean(com.android.internal.R.styleable.ImageView_cropToPadding, false);
		 * 
		 * 
		 * a.recycle();
		 */
		// need inflate syntax/reader for matrix
	}

	private void initImageView() {
		//mMatrix = new Matrix();
		mScaleType = SCALE_TYPE_FIT_CENTER;
	}

	// Override
	protected boolean verifyDrawable(Drawable dr) {
		return mDrawable == dr || super.verifyDrawable(dr);
	}

	// Override
	public void invalidateDrawable(Drawable dr) {

		if (dr == mDrawable) {
			/*
			 * we invalidate the whole view in this case because it's very hard
			 * to know where the drawable actually is. This is made complicated
			 * because of the offsets and transformations that can be applied.
			 * In theory we could get the drawable's bounds and run them through
			 * the transformation and offsets, but this is probably not worth
			 * the effort.
			 */
			invalidate();
		} 
		else {
			super.invalidateDrawable(dr);
		}
	}

	// Override
	protected boolean onSetAlpha(int alpha) {
		if (getBackground() == null) {
			int scale = alpha + (alpha >> 7);
			if (mViewAlphaScale != scale) {
				mViewAlphaScale = scale;
				applyColorMod();
			}
			return true;
		}
		return false;
	}

	/**
	 * Set this to true if you want the ImageView to adjust its bounds to
	 * preserve the aspect ratio of its drawable.
	 * 
	 * @param adjustViewBounds
	 *            Whether to adjust the bounds of this view to presrve the
	 *            original aspect ratio of the drawable
	 * 
	 * @attr ref android.R.styleable#ImageView_adjustViewBounds
	 */

	/*
	 * public void setAdjustViewBounds(boolean adjustViewBounds) {
	 * mAdjustViewBounds = adjustViewBounds; if (adjustViewBounds) {
	 * setScaleType(FIT_CENTER); } }
	 */

	/**
	 * An optional argument to supply a maximum width for this view. Only valid
	 * if {@link #setAdjustViewBounds} has been set to true. To set an image to
	 * be a maximum of 100 x 100 while preserving the original aspect ratio, do
	 * the following: 1) set adjustViewBounds to true 2) set maxWidth and
	 * maxHeight to 100 3) set the height and width layout params to
	 * WRAP_CONTENT.
	 * 
	 * <p>
	 * Note that this view could be still smaller than 100 x 100 using this
	 * approach if the original image is small. To set an image to a fixed size,
	 * specify that size in the layout params and then use {@link #setScaleType}
	 * to determine how to fit the image within the bounds.
	 * </p>
	 * 
	 * @param maxWidth
	 *            maximum width for this view
	 * 
	 * @attr ref android.R.styleable#ImageView_maxWidth
	 */
	public void setMaxWidth(int maxWidth) {
		mMaxWidth = maxWidth;
	}

	/**
	 * An optional argument to supply a maximum height for this view. Only valid
	 * if {@link #setAdjustViewBounds} has been set to true. To set an image to
	 * be a maximum of 100 x 100 while preserving the original aspect ratio, do
	 * the following: 1) set adjustViewBounds to true 2) set maxWidth and
	 * maxHeight to 100 3) set the height and width layout params to
	 * WRAP_CONTENT.
	 * 
	 * <p>
	 * Note that this view could be still smaller than 100 x 100 using this
	 * approach if the original image is small. To set an image to a fixed size,
	 * specify that size in the layout params and then use {@link #setScaleType}
	 * to determine how to fit the image within the bounds.
	 * </p>
	 * 
	 * @param maxHeight
	 *            maximum height for this view
	 * 
	 * @attr ref android.R.styleable#ImageView_maxHeight
	 */
	public void setMaxHeight(int maxHeight) {
		mMaxHeight = maxHeight;
	}

	/**
	 * Return the view's drawable, or null if no drawable has been assigned.
	 */
	public Drawable getDrawable() {
		return mDrawable;
	}

	/**
	 * Sets a drawable as the content of this ImageView.
	 * 
	 * @param resId
	 *            the resource identifier of the the drawable
	 * 
	 * @attr ref android.R.styleable#ImageView_src
	 */
	/*
	 * public void setImageResource(int resId) { if (mUri != null || mResource
	 * != resId) { updateDrawable(null); mResource = resId; mUri = null;
	 * resolveUri(); requestLayout(); invalidate(); } }
	 */

	/**
	 * Sets the content of this ImageView to the specified Uri.
	 * 
	 * @param uri
	 *            The Uri of an image
	 */
	/*
	 * public void setImageURI(Uri uri) { if (mResource != 0 || (mUri != uri &&
	 * (uri == null || mUri == null || !uri.equals(mUri)))) {
	 * updateDrawable(null); mResource = 0; mUri = uri; resolveUri();
	 * requestLayout(); invalidate(); } }
	 */

	/**
	 * Sets a drawable as the content of this ImageView.
	 * 
	 * @param drawable
	 *            The drawable to set
	 */

	public void setImageDrawable(Drawable drawable) {
		
		if (mDrawable != drawable) {
			// mResource = 0;
			// mUri = null;
			
			updateDrawable(drawable);
			requestLayout();
			invalidate();
			
		}
	}

	/**
	 * Sets a Bitmap as the content of this ImageView.
	 * 
	 * @param bm
	 *            The bitmap to set
	 */
	public void setImageBitmap(Bitmap bm) {
		// if this is used frequently, may handle bitmaps explicitly
		// to reduce the intermediate drawable object
		setImageDrawable(new BitmapDrawable(bm));
	}

	public void setImageState(int[] state, boolean merge) {
		mState = state;
		mMergeState = merge;
		if (mDrawable != null) {
			refreshDrawableState();
			resizeFromDrawable();
		}
	}

	// Override
	public void setSelected(boolean selected) {
		super.setSelected(selected);
		resizeFromDrawable();
	}

	public void setImageLevel(int level) {
		mLevel = level;
		if (mDrawable != null) {
			mDrawable.setLevel(level);
			resizeFromDrawable();
		}
	}

	/**
	 * Controls how the image should be resized or moved to match the size of
	 * this ImageView.
	 * 
	 * @param scaleType
	 *            The desired scaling mode.
	 * 
	 * @attr ref android.R.styleable#ImageView_scaleType
	 */
	public void setScaleType(int scaleType) {
		/*
		 * if (scaleType == null) { throw new NullPointerException(); }
		 */

		if (mScaleType != scaleType) {
			mScaleType = scaleType;

			//setWillNotCacheDrawing(mScaleType == SCALE_TYPE_CENTER);

			requestLayout();
			invalidate();
		}
	}

	/**
	 * Return the current scale type in use by this ImageView.
	 * 
	 * @see ImageView.ScaleType
	 * 
	 * @attr ref android.R.styleable#ImageView_scaleType
	 */
	public int getScaleType() {
		return mScaleType;
	}

	/**
	 * Return the view's optional matrix. This is applied to the view's drawable
	 * when it is drawn. If there is not matrix, this method will return null.
	 * Do not change this matrix in place. If you want a different matrix
	 * applied to the drawable, be sure to call setImageMatrix().
	 */

	/*
	 * public Matrix getImageMatrix() { return mMatrix; }
	 * 
	 * public void setImageMatrix(Matrix matrix) { // collaps null and identity
	 * to just null if (matrix != null && matrix.isIdentity()) { matrix = null;
	 * }
	 * 
	 * // don't invalidate unless we're actually changing our matrix if (matrix
	 * == null && !mMatrix.isIdentity() || matrix != null &&
	 * !mMatrix.equals(matrix)) { mMatrix.set(matrix); invalidate(); } }
	 */

	/*
	 * private void resolveUri() { if (mDrawable != null) { return; }
	 * 
	 * Resources rsrc = getResources(); if (rsrc == null) { return; }
	 * 
	 * Drawable d = null;
	 * 
	 * if (mResource != 0) { try { d = rsrc.getDrawable(mResource); } catch
	 * (Exception e) { Log.w("ImageView", "Unable to find resource: " +
	 * mResource, e); // Don't try again. mUri = null; } } else if (mUri !=
	 * null) { if ("content".equals(mUri.getScheme())) { try { d =
	 * Drawable.createFromStream(
	 * mContext.getContentResolver().openInputStream(mUri), null); } catch
	 * (Exception e) { Log.w("ImageView", "Unable to open content: " + mUri, e);
	 * } } else { d = Drawable.createFromPath(mUri.toString()); }
	 * 
	 * if (d == null) {
	 * System.out.println("resolveUri failed on bad bitmap uri: " + mUri); //
	 * Don't try again. mUri = null; } } else { return; }
	 * 
	 * updateDrawable(d); }
	 */

	// Override
	public int[] onCreateDrawableState(int extraSpace) {
		
		if (mState == null) {
			return super.onCreateDrawableState(extraSpace);
		} 
		else if (!mMergeState) {
			return mState;
		} 
		else {
			return mergeDrawableStates(super.onCreateDrawableState(extraSpace+ mState.length), mState);
		}
	}

	private void updateDrawable(Drawable d) {
		
		if (mDrawable != null) {
			mDrawable.setCallback(null);
			unscheduleDrawable(mDrawable);
		}
		mDrawable = d;
		if (d != null) {
			d.setCallback(this);
			if (d.isStateful()) {
				d.setState(getDrawableState());
			}
			d.setLevel(mLevel);
			mDrawableWidth = d.getIntrinsicWidth();
			mDrawableHeight = d.getIntrinsicHeight();
			applyColorMod();
			configureBounds();
		}
	}

	private void resizeFromDrawable() {
		
		Drawable d = mDrawable;
		if (d != null) {
			int w = d.getIntrinsicWidth();
			if (w < 0)
				w = mDrawableWidth;
			int h = d.getIntrinsicHeight();
			if (h < 0)
				h = mDrawableHeight;
			if (w != mDrawableWidth || h != mDrawableHeight) {
				mDrawableWidth = w;
				mDrawableHeight = h;
				requestLayout();
			}
		}
	}

	/*
	 * private static final Matrix.ScaleToFit[] sS2FArray = {
	 * Matrix.ScaleToFit.FILL, Matrix.ScaleToFit.START,
	 * Matrix.ScaleToFit.CENTER, Matrix.ScaleToFit.END };
	 * 
	 * private static Matrix.ScaleToFit scaleTypeToScaleToFit(ScaleType st) { //
	 * ScaleToFit enum to their corresponding Matrix.ScaleToFit values return
	 * sS2FArray[st.nativeInt - 1]; }
	 */

	// Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

		// resolveUri();
		int w;
		int h;

		// Desired aspect ratio of the view's contents (not including padding)
		float desiredAspect = 0.0f;

		// We are allowed to change the view's width
		boolean resizeWidth = false;

		// We are allowed to change the view's height
		boolean resizeHeight = false;

		if (mDrawable == null) {
			// If no drawable, its intrinsic size is 0.
			mDrawableWidth = -1;
			mDrawableHeight = -1;
			w = h = 0;
		} else {
			w = mDrawableWidth;
			h = mDrawableHeight;
			if (w <= 0)
				w = 1;
			if (h <= 0)
				h = 1;

			// We are supposed to adjust view bounds to match the aspect
			// ratio of our drawable. See if that is possible.
			if (mAdjustViewBounds) {

				int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);
				int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);

				resizeWidth = widthSpecMode != MeasureSpec.EXACTLY;
				resizeHeight = heightSpecMode != MeasureSpec.EXACTLY;

				desiredAspect = (float) w / (float) h;
			}
		}

		int pleft = mPaddingLeft;
		int pright = mPaddingRight;
		int ptop = mPaddingTop;
		int pbottom = mPaddingBottom;

		int widthSize;
		int heightSize;

		if (resizeWidth || resizeHeight) {
			/*
			 * If we get here, it means we want to resize to match the drawables
			 * aspect ratio, and we have the freedom to change at least one
			 * dimension.
			 */

			// Get the max possible width given our constraints
			widthSize = resolveAdjustedSize(w + pleft + pright, mMaxWidth,widthMeasureSpec);

			// Get the max possible height given our constraints
			heightSize = resolveAdjustedSize(h + ptop + pbottom, mMaxHeight,heightMeasureSpec);

			if (desiredAspect != 0.0f) {
				// See what our actual aspect ratio is
				float actualAspect = (float) (widthSize - pleft - pright)
						/ (heightSize - ptop - pbottom);

				if (Math.abs(actualAspect - desiredAspect) > 0.0000001) {

					boolean done = false;

					// Try adjusting width to be proportional to height
					if (resizeWidth) {
						int newWidth = (int) (desiredAspect * (heightSize
								- ptop - pbottom))
								+ pleft + pright;
						if (newWidth <= widthSize) {
							widthSize = newWidth;
							done = true;
						}
					}

					// Try adjusting height to be proportional to width
					if (!done && resizeHeight) {
						int newHeight = (int) ((widthSize - pleft - pright) / desiredAspect)
								+ ptop + pbottom;
						if (newHeight <= heightSize) {
							heightSize = newHeight;
						}
					}
				}
			}
		} 
		else {
			/*
			 * We are either don't want to preserve the drawables aspect ratio,
			 * or we are not allowed to change view dimensions. Just measure in
			 * the normal way.
			 */
			w += pleft + pright;
			h += ptop + pbottom;

			w = Math.max(w, getSuggestedMinimumWidth());
			h = Math.max(h, getSuggestedMinimumHeight());

			widthSize = resolveSize(w, widthMeasureSpec);
			heightSize = resolveSize(h, heightMeasureSpec);
		}

		setMeasuredDimension(widthSize, heightSize);
	}

	private int resolveAdjustedSize(int desiredSize, int maxSize,int measureSpec) {
		int result = desiredSize;
		int specMode = MeasureSpec.getMode(measureSpec);
		int specSize = MeasureSpec.getSize(measureSpec);

		switch (specMode) {
		case MeasureSpec.UNSPECIFIED:
			/*
			 * Parent says we can be as big as we want. Just don't be larger
			 * than max size imposed on ourselves.
			 */
			result = Math.min(desiredSize, maxSize);
			break;
		case MeasureSpec.AT_MOST:
			// Parent says we can be as big as we want, up to specSize.
			// Don't be larger than specSize, and don't be larger than
			// the max size imposed on ourselves.
			result = Math.min(Math.min(desiredSize, specSize), maxSize);
			break;
		case MeasureSpec.EXACTLY:
			// No choice. Do what we are told.
			result = specSize;
			break;
		}
		return result;
	}

	// Override
	protected boolean setFrame(int l, int t, int r, int b) {
		boolean changed = super.setFrame(l, t, r, b);
		mHaveFrame = true;
		configureBounds();
		return changed;
	}

	private void configureBounds() {
		
		if (mDrawable == null || !mHaveFrame) {
			return;
		}

		int dwidth = mDrawableWidth;
		int dheight = mDrawableHeight;

		int vwidth = getWidth() - mPaddingLeft - mPaddingRight;
		int vheight = getHeight() - mPaddingTop - mPaddingBottom;

		if (dwidth <= 0 || dheight <= 0 || SCALE_TYPE_FIT_XY == mScaleType) {

			// If the drawable has no intrinsic size, or we're told to
			// scaletofit, then we just fill our entire view.

			mDrawable.setBounds(0, 0, vwidth, vheight);

			// mDrawMatrix = null;
		} 
		else {
			// We need to do the scaling ourself, so have the drawable
			// use its native size.

			boolean fits = (dwidth < 0 || vwidth == dwidth)
					&& (dheight < 0 || vheight == dheight);

			mDrawable.setBounds(0, 0, dwidth, dheight);
			/*
			 * if (SCALE_TYPE_MATRIX == mScaleType) { // Use the specified
			 * matrix as-is. if (mMatrix.isIdentity()) { mDrawMatrix = null; }
			 * else { mDrawMatrix = mMatrix; }
			 * 
			 * } else
			 */
			if (fits) {

				// The bitmap fits exactly, no transform needed.
				// mDrawMatrix = null;
			} else if (SCALE_TYPE_CENTER == mScaleType) {

				// Center bitmap in view, noscaling.
				// mDrawMatrix = mMatrix;
				// mDrawMatrix.setTranslate((vwidth - dwidth) * 0.5f, (vheight -
				// dheight) * 0.5f);
			} 
			else if (SCALE_TYPE_CENTER_CROP == mScaleType) {
				
				/*
				mDrawMatrix = mMatrix;

				float scale;
				float dx = 0, dy = 0;

				if (dwidth * vheight > vwidth * dheight) {
					scale = (float) vheight / (float) dheight;
					dx = (vwidth - dwidth * scale) * 0.5f;
				} else {
					scale = (float) vwidth / (float) dwidth;
					dy = (vheight - dheight * scale) * 0.5f;
				}

				// mDrawMatrix.setScale(scale, scale);
				// mDrawMatrix.postTranslate(dx,dy);
				*/
			} 
			else if (SCALE_TYPE_CENTER_INSIDE == mScaleType) {
				
				/*
				mDrawMatrix = mMatrix;
				float scale;
		

				if (dwidth <= vwidth && dheight <= vheight) {
					scale = 1.0f;
				} else {
					scale = Math.min((float) vwidth / (float) dwidth, (float) vheight / (float) dheight);
				}

				float dx = (vwidth - dwidth * scale) * 0.5f;
				float dy = (vheight - dheight * scale) * 0.5f;
				mDrawMatrix.setScale(scale, scale);
				mDrawMatrix.postTranslate(dx,dy);
				*/
			} 
			else {
				// Generate the required transform.
				//mTempSrc.set(0, 0, dwidth, dheight);
				//mTempDst.set(0, 0, vwidth, vheight);
				// mDrawMatrix = mMatrix;
				// mDrawMatrix.setRectToRect(mTempSrc,
				// mTempDst,scaleTypeToScaleToFit(mScaleType));
			}
		}

	}

	// Override
	protected void drawableStateChanged() {

		super.drawableStateChanged();
		Drawable d = mDrawable;
		if (d != null && d.isStateful()) {
			d.setState(getDrawableState());
		}
	}

	// Override
	protected void onDraw(Canvas canvas) {

		super.onDraw(canvas);
		//Log.i("ImageView", "this.mLeft " + this.mLeft );
		//Log.i("ImageView", "this.mRight " + this.mRight );
		//Log.i("ImageView", "this.mTop " + this.mTop );
		//Log.i("ImageView", "this.mBottom " + this.mBottom );
		
		if (mDrawable == null) {
			return; // couldn't resolve the URI
		}

		if (mDrawableWidth == 0 || mDrawableHeight == 0) {
			return; // nothing to draw (empty bounds)
		}

		int saveCount = canvas.getSaveCount();
		canvas.save();
		
		if(SCALE_TYPE_CENTER == mScaleType) {
			canvas.translate((getWidth()-mDrawableWidth)/2,0);
		}
		
		
		if (mPaddingTop == 0 && mPaddingLeft == 0) {
			mDrawable.draw(canvas);
		} 
		else {

			if (mCropToPadding) {
				final int scrollX = mScrollX;
				final int scrollY = mScrollY;
				canvas.clipRect(scrollX + mPaddingLeft, scrollY + mPaddingTop,
						scrollX + mRight - mLeft - mPaddingRight, scrollY
								+ mBottom - mTop - mPaddingBottom);
			}

			canvas.translate(mPaddingLeft, mPaddingTop);

			
		
			
			/*
			 * matrix translation not supported 
			 * 
			 * if (mDrawMatrix != null) {
			 * canvas.concat(mDrawMatrix); }
			 */

			mDrawable.draw(canvas);
			
			
		}
		
		canvas.restoreToCount(saveCount);
	}

	// Override
	public int getBaseline() {
		return mBaselineAligned ? getHeight() : -1;
	}

	/**
	 * Set a tinting option for the image.
	 * 
	 * @param color
	 *            Color tint to apply.
	 * @param mode
	 *            How to apply the color. The standard mode is
	 *            {@link PorterDuff.Mode#SRC_ATOP}
	 * 
	 * @attr ref android.R.styleable#ImageView_tint
	 */

	/*
	 * public final void setColorFilter(int color, PorterDuff.Mode mode) {
	 * setColorFilter(new PorterDuffColorFilter(color, mode)); }
	 * 
	 * public final void clearColorFilter() { setColorFilter(null); }
	 */

	/**
	 * Apply an arbitrary colorfilter to the image.
	 * 
	 * @param cf
	 *            the colorfilter to apply (may be null)
	 */

	/*
	 * public void setColorFilter(ColorFilter cf) { if (mColorFilter != cf) {
	 * mColorFilter = cf; applyColorMod(); invalidate(); } }
	 */

	/*
	 * public void setAlpha(int alpha) { alpha &= 0xFF; // keep it legal
	 * if(mAlpha != alpha) { mAlpha = alpha; applyColorMod(); invalidate(); } }
	 */

	private void applyColorMod() {
		/*
		 * if (mDrawable != null) { mDrawable.setColorFilter(mColorFilter);
		 * mDrawable.setAlpha(mAlpha * mViewAlphaScale >> 8); }
		 */
	}

}
